/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an 'AS IS' BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef IMAGE_KNIFE_C_KEKE_PIXELMAP_UTILS_H
#define IMAGE_KNIFE_C_KEKE_PIXELMAP_UTILS_H
#include "log.h"
#include <multimedia/image_framework/image/pixelmap_native.h>
#include "image_data.h"

namespace ImageKnifePro {

class PixelmapUtils {
public:
    static void SetMemoryName(std::shared_ptr<ImageData> data, std::string name);

    static Image_Size GetImageSize(OH_PixelmapNative *data)
    {
        Image_Size imageSize = {0, 0};
        IMAGE_KNIFE_CHECK_RETURN(data == nullptr, imageSize);
        OH_Pixelmap_ImageInfo *imageInfo = nullptr;
        Image_ErrorCode errorCode = OH_PixelmapImageInfo_Create(&imageInfo);
        if (errorCode != IMAGE_SUCCESS) {
            IMAGE_KNIFE_LOG(LOG_ERROR, "GetImageSize Create ImageInfo Failed: %{public}d", errorCode);
            return imageSize;
        }
        errorCode = OH_PixelmapNative_GetImageInfo(data, imageInfo);
        if (errorCode != IMAGE_SUCCESS) {
            IMAGE_KNIFE_LOG(LOG_ERROR, "GetImageSize Get ImageInfo Failed: %{public}d", errorCode);
            OH_PixelmapImageInfo_Release(imageInfo);
            return imageSize;
        }

        OH_PixelmapImageInfo_GetWidth(imageInfo, &imageSize.width);
        OH_PixelmapImageInfo_GetHeight(imageInfo, &imageSize.height);
        OH_PixelmapImageInfo_Release(imageInfo);
        return imageSize;
    }

    // 通过图片"Orientation"属性元信息旋转镜像pixelmap
    static void Orientate(std::shared_ptr<ImageData> data, std::string orientation)
    {
        IMAGE_KNIFE_CHECK(data == nullptr);
        IMAGE_KNIFE_CHECK(data->GetFrameCount() < 1);
        auto pixelmapList = data->GetPixelmapList();
        IMAGE_KNIFE_CHECK(pixelmapList == nullptr);
        
        auto func = GetOrientateFunc(orientation);
        if (func == nullptr) {
            return;
        }

        for (int i = 0; i < data->GetFrameCount(); i++) {
            func(pixelmapList[i]);
        }
    }

    // 通过枚举旋转镜像pixelmap
    static void Orientate(std::shared_ptr<ImageData> data, Orientation orientation)
    {
        // Auto 需要获取图片exif元数据，只在解码时进行
        if (orientation == Orientation::AUTO) {
            return;
        }

        // Orientation::UP 无需操作
        static std::unordered_map<Orientation, std::string> enumMap = {
            {Orientation::DOWN, "Bottom-right"},
            {Orientation::LEFT, "Left-bottom"},
            {Orientation::RIGHT, "Right-top"},
        };

        if (enumMap.find(orientation) != enumMap.end()) {
            Orientate(data, enumMap[orientation]);
        }
    }
private:
    // 通过图片"Orientation"属性获取对应操作函数，图片exif元数据是字符串
    static std::function<void(OH_PixelmapNative *)> GetOrientateFunc(std::string orientation)
    {
        const float rotate90 = 90;
        const float rotate180 = 180;
        const float rotate270 = 270;
        static std::unordered_map<std::string, std::function<void(OH_PixelmapNative *)>> funcMap = {
            // 图像未旋转
            {"Top-left", nullptr},
            // 镜像水平翻转
            {"Top-right", [](OH_PixelmapNative *pixelmap) {OH_PixelmapNative_Flip(pixelmap, true, false);}},
            // 图像旋转180°
            {"Bottom-right", [rotate180](OH_PixelmapNative *pixelmap) {
                OH_PixelmapNative_Rotate(pixelmap, rotate180);
            }},
            // 镜像垂直翻转
            {"Bottom-left", [](OH_PixelmapNative *pixelmap) {OH_PixelmapNative_Flip(pixelmap, false, true);}},
            // 镜像水平翻转再顺时针旋转270°
            {"Left-top", [rotate270](OH_PixelmapNative *pixelmap) {
                OH_PixelmapNative_Flip(pixelmap, true, false);
                OH_PixelmapNative_Rotate(pixelmap, rotate270);
            }},
            // 顺时针旋转90°
            {"Right-top", [rotate90](OH_PixelmapNative *pixelmap) {
                OH_PixelmapNative_Rotate(pixelmap, rotate90);
            }},
            // 镜像水平翻转再顺时针旋转90°
            {"Right-bottom", [rotate90](OH_PixelmapNative *pixelmap) {
                OH_PixelmapNative_Flip(pixelmap, true, false);
                OH_PixelmapNative_Rotate(pixelmap, rotate90);
            }},
            // 顺时针旋转270°
            {"Left-bottom", [rotate270](OH_PixelmapNative *pixelmap) {
                OH_PixelmapNative_Rotate(pixelmap, rotate270);
            }},
        };

        if (funcMap.find(orientation) != funcMap.end()) {
            return funcMap[orientation];
        }
        return nullptr;
    }
};
}
#endif //IMAGE_KNIFE_C_KEKE_PIXELMAP_UTILS_H
